using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ShellAnywhere.Model
{
	public enum Change
	{
		Postion,
		Cleared,
		Added
	}

	public class StreamChangedEventArgs : EventArgs
	{
		public StreamChangedEventArgs(Change change) { Change = change; }
		public Change Change { get; set; }
	}
	public delegate void StreamChangedEventHandler(object sender, StreamChangedEventArgs e);

	public class Stream<T>
	{
		#region ctors
		public Stream()
		{
			Position = 0;
			Items = new List<T>();
		}
		public Stream(T[] itemArray)
		{
			Position = 0;
			Items = new List<T>(itemArray);
		}
		public Stream(List<T> itemList)
		{
			Position = 0;
			Items = itemList;
		}
		#endregion ctors

		#region properties
		public int Count { get { return Items.Count; } }
		private int _Position;
		public int Position
		{
			get { return _Position; }
			set
			{
				if (_Position != value)
				{
					_Position = value;
					if (StreamChanged != null)
						StreamChanged(this, new StreamChangedEventArgs(Change.Postion));

				}
			}
		}
		public List<T> Items { get; set; }

		public T PrevItem()
		{
			T prevItem = default(T);
			if (!IsEmpty && Position > 0)
				prevItem = Items[Position - 1];
			return prevItem;
		}
		public T NextItem()
		{
			T nextItem = default(T);
			if (!IsEndOfStream)
				nextItem = Items[Position++];
			return nextItem;
		}
		public T PeekItem()
		{
			T peekItem = default(T);
			if (!IsEndOfStream)
				peekItem = Items[Position];
			return peekItem;
		}

		public bool IsEmpty { get { return Items != null && Items.Count == 0; } }
		public bool IsEndOfStream { get { return IsEmpty || Position >= Items.Count; } }

		#endregion properties

		#region methods
		public void ClearItems() 
		{
			if (Items.Count > 0)
			{
				Items.Clear();
				_Position = 0;
				if (StreamChanged != null)
					StreamChanged(this, new StreamChangedEventArgs(Change.Cleared));
			}
		}
		public void AddItems(params T[] items)
		{
			if (items != null)
			{
				foreach (T item in items)
					Items.Add(item);
				if (StreamChanged != null)
					StreamChanged(this, new StreamChangedEventArgs(Change.Added));
			}
		}
		#endregion methods

		#region events
		public event StreamChangedEventHandler StreamChanged;
		#endregion events

		#region fields
		#endregion fields
	}
}
